home *** CD-ROM | disk | FTP | other *** search
- /*
- * Simple mail user interface for KA9Q IP/TCP package.
- * A.D. Barksdale Garbee II, aka Bdale, N3EUA
- * Copyright 1986 Bdale Garbee, All Rights Reserved.
- * Permission granted for non-commercial copying and use, provided
- * this notice is retained.
- * Copyright 1987 1988 Dave Trulli NN2Z, All Rights Reserved.
- * Permission granted for non-commercial copying and use, provided
- * this notice is retained.
- *
- * Ported to NOS at 900120 by Anders Klemets SM0RGV.
- *
- * Userlogging, 'RM' and 'KM' implementation,
- * more-prompts for all types
- * 920307 and later, by Johan. K. Reinalda, WG7J/PA3DIS
- * 920719 and later, by Brian A. Lantz, KO4KS
- */
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <io.h>
- #include "global.h"
- #include "config.h"
- #include "ftpserv.h"
- #include "smtp.h"
- #include "proc.h"
- #include "usock.h"
- #include "socket.h"
- #include "telnet.h"
- #include "timer.h"
- #include "session.h"
- #include "files.h"
- #include "mailbox.h"
- #include "cmdparse.h"
- #include "bm.h"
- #include "mailutil.h"
-
- #define SETVBUF
- #if defined(UNIX) || defined(MICROSOFT)
- #include <sys/types.h>
- #endif
- /*
- #if defined(UNIX) || defined(MICROSOFT) || defined(__TURBOC__)
- #include <sys/stat.h>
- #endif
- #ifdef AZTEC
- #include <stat.h>
- #endif
- */
- #include <fcntl.h>
- #include "bm.h"
- #include "mailbox.h"
-
- #ifdef SETVBUF
- #define MYBUF 1024
- #endif
-
- extern long ftell();
- char Badmsg[] = "Invalid Message number %d\n";
- char Nomail[] = "No messages\n";
- static char NoMsgs[] = "No message numbers given\n";
- static char anymore[] = "More(N=no)? ";
- static char Noaccess[] = "Unable to access %s\n";
- static int readnotes __ARGS((struct mbx *m, int already));
- static long isnewmail __ARGS((struct mbx *m));
- static int initnotes __ARGS((struct mbx *m));
- int lockit __ARGS((struct mbx *m));
- long fsize __ARGS((char *name));
- static void mfclose __ARGS((struct mbx *m));
-
- #ifdef MAILBOX
-
- static int
- initnotes(m)
- struct mbx *m;
- {
- register struct let *cmsg;
- char buf[256];
- int i, ret;
- int wasit = 0;
-
- if (m->mfile != NULLFILE) {
- fclose (m->mfile);
- wasit = m->nmsgs;
- }
- sprintf(buf,"%s/%s.txt",Mailspool,m->area);
- if ((m->mfile = fopen(buf,READ_TEXT)) == NULLFILE)
- return 0;
- m->mboxsize = filelength (fileno(m->mfile));
- if(!(m->sid & MBX_SID) && !stricmp(m->area,m->name)) /* our private mail area */
- m->mysize = m->mboxsize;
- m->nmsgs = 0;
- m->change = 0;
- m->newmsgs = 0;
- m->anyread = 0;
- /* Allocate space for reading messages */
- readnotes(m, wasit);
- #ifdef USERLOG
- m->current = 0; /*reset it*/
- if (m->nmsgs)
- for (cmsg = &m->mbox[1],i = 1; i <= m->nmsgs; i++, cmsg++)
- if ((cmsg->status & BM_READ) == 0) {
- m->current = i; /* first new message */
- break;
- }
-
- /* start at one if no new messages */
- if ((m->current == 0) && m->nmsgs)
- m->current++;
- #endif
- return 0;
- }
-
- /* readnotes assumes that ifile is pointing to the first
- * message that needs to be read. For initial reads of a
- * notesfile, this will be the beginning of the file. For
- * rereads when new mail arrives, it will be the first new
- * message.
- */
- static int
- readnotes(m, already)
- register struct mbx *m;
- int already;
- {
- register FILE *fp;
- char mailbox[100];
- long size;
- register int i, isit;
- register struct let *cmsg;
- struct let *new;
-
- m->newmsgs = m->hmsgs = 0;
- sprintf(mailbox,"%s/CONTROL/%s.ctl",Mailspool,m->area);
- if((fp = fopen(mailbox,READ_BINARY)) != NULLFILE){
- #ifndef TNOS_68K
- m->stdoutbuf = mallocw(MYBUF);
- setvbuf(fp, m->stdoutbuf, _IOFBF, MYBUF);
- #endif
- size = filelength (fileno(fp));
- /* fseek (fp, 0L, 2);
- size = ftell (fp);
- fseek (fp, 0L, 0); */
- new = (struct let *) malloc (size + sizeof(struct let));
- fread (&new[1], size, 1, fp);
- fclose(fp);
- if (already && !strcmp (m->area, m->name))
- memcpy (new, m->mbox, (already + 1) * sizeof(struct let));
- #ifndef TNOS_68K
- free (m->stdoutbuf);
- m->stdoutbuf = 0;
- #endif
- free (m->mbox);
- m->mbox = new;
- m->nmsgs = (int) (size / (long) sizeof(struct let));
- isit = issysarea (m->area);
- for (cmsg = &m->mbox[1],i = 1; i <= m->nmsgs; i++, cmsg++)
- if (isit) {
- if ((cmsg->bid > m->lastread) && !(cmsg->status & BM_DELETE))
- m->newmsgs++;
- else
- cmsg->status |= BM_READ;
- if (cmsg->status & BM_ONHOLD)
- m->hmsgs++;
- } else if (!(cmsg->status & BM_READ))
- m->newmsgs++;
- }
- else
- m->nmsgs = 0;
- return 0;
- }
-
- /* list headers of a notesfile a message */
- /* Rearranged display - WG7J */
- int
- dolistnotes(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mbx *m;
- struct let *cmsg;
- char *cp, *s;
- char smtp_date[SLINELEN], smtp_from[SLINELEN];
- char smtp_subject[SLINELEN], tstring[LINELEN], type;
- char smtp_to[SLINELEN], smtp_bid[30];
- int start, stop;
- long size;
- char *area;
- int c,usemore=0,lin;
- #ifdef USERLOG
- long msgid;
- #endif
-
- m = (struct mbx *) p;
-
- /*If this user doesn't have read-permissions,
- *we're not going to let him list anything - WG7J */
- if(m->privs & NO_READCMD) {
- tputs(Noperm);
- return 0;
- }
-
- if (m->mfile == NULLFILE) {
- tputs(Nomail);
- return 0;
- }
- if((m->stype == 'S' || m->stype == '$' || m->stype == '>' || m->stype == '<') && argc == 1) {
- tputs("Search criterium needed!\n");
- return 0;
- }
-
- if((lin=m->morerows) != 0)
- usemore = 1; /* Display More prompt */
-
- area = strdup(m->area);
- while((cp = strchr(area,'/')) != NULLCHAR)
- *cp = '.';
- bbscolorcls (m);
- tprintf("Mail area: ");
- bbscolorchange (m, "09");
- tprintf (area);
- bbscolorchange (m, "0B");
- tprintf (" %d ", m->nmsgs);
- bbscolorchange (m, "0F");
- tprintf ("message%s - ",m->nmsgs == 1 ? " " : "s ");
- bbscolorchange (m, "0B");
- tprintf ("%d ", m->newmsgs);
- bbscolorchange (m, "0F");
- tprintf ("new\n\nStat # TO FROM DATE SIZE SUBJECT\n");
- free(area);
-
- stop = m->nmsgs;
- if(m->stype == 'L') { /* LL (List Latest) command */
- if(argc > 1)
- start = stop - atoi(argv[1]) + 1;
- else
- start = stop;
- if (start < 1)
- start = 1;
- } else {
- if((m->stype == 'A') || (m->stype == '>') || (m->stype == '<') || (m->stype == 'S') || (m->stype == '$')) {
- start = 1;
- stop = m->nmsgs;
- } else {
- if(argc > 1)
- start = atoi(argv[1]);
- else
- #ifdef USERLOG
- start = m->nmsgs - m->newmsgs + 1;
- #else
- start = 1;
- #endif
- if(argc > 2)
- stop = atoi(argv[2]);
- }
- }
- if(stop > m->nmsgs)
- stop = m->nmsgs;
- if(start < 1 || start > stop) {
- if((m->stype == ' ') || (m->stype == 'M'))
- tputs("No new mail.\n");
- else
- tputs("Invalid range.\n");
- return 0;
- }
- for (cmsg = &m->mbox[start]; start <= stop; start++, cmsg++) {
- *smtp_date = '\0';
- *smtp_from = '\0';
- *smtp_subject = '\0';
- *smtp_to = '\0';
- *smtp_bid = '\0';
- type = ' ';
- fseek(m->mfile,cmsg->start,0);
- size = cmsg->size;
- /* Be a little less selfish - WG7J */
- pwait(NULL);
-
- #ifdef USERLOG
- /* We need to get the id from the last message listed !
- * m->mbox[i].start (ie cmsg->start) points to the 'From ' line
- * next are the 'Received....' and 'ID...' lines
- * These are thes line added by our smtp server.
- * following the 'AA' is the number that we want ! - WG7J
- */
- if(start == stop) {
- /*The 'From ' line*/
- fgets(tstring,sizeof(tstring),m->mfile);
- size -= strlen(tstring);
- /*The 'Received' line*/
- fgets(tstring,sizeof(tstring),m->mfile);
- size -= strlen(tstring);
- /*The 'ID' line*/
- fgets(tstring,sizeof(tstring),m->mfile);
- size -= strlen(tstring);
- /* find id number */
- #ifndef nope
- if((cmsg->bid > m->lastread) && (cmsg->bid > m->newlastread))
- m->newlastread = cmsg->bid;
- #else
- if((cp=strstr(tstring,"AA")) != NULLCHAR) {
- /*what follows is the message-number*/
- msgid = atol(cp+2);
- if((msgid > m->lastread) && (msgid > m->newlastread))
- m->newlastread = msgid;
- }
- #endif
- }
- #endif
-
- while (size > 0 && fgets(tstring,sizeof(tstring),m->mfile) != NULLCHAR) {
- pwait(NULL);
- if (*tstring == '\n') /* end of header */
- break;
- size -= strlen(tstring);
- rip(tstring);
- /* handle continuation later */
- if (*tstring == ' '|| *tstring == '\t')
- continue;
- switch(htype(tstring)) {
- case FROM: cp = getaddress(tstring,0);
- strncpy(smtp_from,cp != NULLCHAR ? cp : "", 8);
- if((cp=strchr(smtp_from,'@')) != NULLCHAR)
- *cp = '\0'; /* get rid of @-host or @-bbs field */
- break;
- case SUBJECT: strncpy (smtp_subject,&tstring[9], 35);
- break;
- case MSGID: strncpy (smtp_bid,&tstring[12], 29);
- break;
- case DATE: if ((cp = strchr(tstring,',')) == NULLCHAR)
- cp = &tstring[6];
- else
- cp++;
- /* skip spaces */
- while (*cp == ' ') cp++;
- if(strlen(cp) < 17)
- break; /* not a valid length */
- s = smtp_date;
- /* copy day */
- if (atoi(cp) < 10 && *cp != '0')
- *s++ = ' ';
- else
- *s++ = *cp++;
- *s++ = *cp++;
-
- *s++ = ' ';
- *s = '\0';
- while (*cp == ' ')
- cp++;
- strncat(s,cp,3); /* copy month */
- #ifdef use_time
- cp += 3;
- while (*cp == ' ')
- cp++;
- /* skip year */
- while (isdigit(*cp))
- cp++;
- /* copy time */
- strncat(s,cp,6); /* space hour : min */
- #endif
- break;
- case BBSTYPE: type = tstring[16];
- break;
- case TO: strncpy (smtp_to,&tstring[4], 13);
- break;
- case NOHEADER: break;
- }
- }
- if(m->stype == ' ' || m->stype == 'L' || m->stype == 'M' ||
- m->stype == 'A' || (type == m->stype && m->stype != ' ') ||
- ((m->stype == 'S') && (strstr(strlwr(smtp_subject),argv[1]) != NULLCHAR)) ||
- ((m->stype == '<') && (strstr(strlwr(smtp_from),argv[1]) != NULLCHAR)) ||
- ((m->stype == '$') && (strstr(strlwr(smtp_bid),argv[1]) != NULLCHAR)) ||
- ((m->stype == '>') && (strstr(strlwr(smtp_to),argv[1]) != NULLCHAR))) {
- lin--;
- if ((cmsg->status & BM_DELETE) && !(m->privs & SYSOP_CMD))
- strcpy (smtp_subject, "[DELETED]");
- bbscolorchange (m, "07");
- tprintf("%c%c%c%c%3d ",
- (start == m->current ? '>' : ' '),
- (cmsg->status & BM_ONHOLD ? 'H' :
- cmsg->status & BM_DELETE ? 'D' : ' '),
- (cmsg->status & BM_READ ? 'Y' : 'N'),
- (cmsg->status & BM_PERMANENT) ? 'P' : ' ',
- start);
- bbscolorchange (m, "0E");
- tprintf("%13.13s ",smtp_to);
- bbscolorchange (m, "0C");
- tprintf("%8.8s ",smtp_from);
- bbscolorchange (m, "07");
- tprintf("%-7.7s ",smtp_date);
- tprintf("%5ld ",cmsg->size);
- bbscolorchange (m, "0E");
- tprintf("%.34s\n", smtp_subject);
- }
- /* More prompting added - WG7J */
- if(usemore && lin == 0) {
- if(m->type == TELNET || m->type == TIP)
- c = tkeywait("--More--",0);
- else /* For AX.25 and NET/ROM connects - WG7J */
- c = mykeywait(anymore, m);
- if(c == -1 || c == 'q' || c == 'Q' || c == 'n' || c == 'N')
- break;
- #ifdef TNOS_68K
- if(c == '\l' || c == '\r')
- #else
- if(c == '\n' || c == '\r')
- #endif
- lin = 1;
- else
- lin = m->morerows;
-
- }
- }
- return 0;
- }
-
- /* save msg on stream - if noheader set don't output the header */
- int
- msgtofile(m,msg,tfile,noheader)
- struct mbx *m;
- int msg;
- FILE *tfile; /* already open for write */
- int noheader;
- {
- char tstring[LINELEN];
- long size;
-
- if (m->mfile == NULLFILE) {
- tprintf(Nomail);
- return -1;
- }
- fseek(m->mfile,m->mbox[msg].start,0);
- size = m->mbox[msg].size;
-
- if (noheader) {
- /* skip header */
- while (size > 0 && fgets(tstring,sizeof(tstring),m->mfile)
- != NULLCHAR) {
- size -= strlen(tstring);
- if (*tstring == '\n')
- break;
- }
- }
- while (size > 0 && fgets(tstring,sizeof(tstring),m->mfile)
- != NULLCHAR) {
- size -= strlen(tstring);
- fputs(tstring,tfile);
- if (ferror(tfile)) {
- tprintf("Error writing mail file\n");
- return -1;
- }
- }
- return 0;
- }
-
- /* dodelmsg - delete message in current notesfile */
- /* Modified to allow the 'KM' command. 920307 - WG7J */
- /* also handles holsing/releasing messages - KO4KS */
- int
- dodelmsg(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mbx *m;
- int msg,i;
- char *myargv[NARG];
- int myargc;
- int maxmsg;
- struct let *cmsg;
- char *tmpbuf;
-
- m = (struct mbx *) p;
-
- /* If this user doesn't have read-permissions,
- * we're not going to let him kill/hold anything;
- * allow anyone to kill/hold messages in areas
- * who's names start with 'nts' - WG7J
- */
- /* Check if we have permission to delete others mail */
- if( (m->privs & NO_READCMD) || (m->privs & NO_SENDCMD) ||
- ( !(m->privs & FTP_WRITE) &&
- stricmp(m->area,m->name) &&
- strnicmp(m->area,"nts",3)) ){
- tputs(Noperm);
- return 0;
- }
- if ((m->stype == 'A' || m->stype == 'H' || m->stype == 'P' || m->stype == 'T') && !(m->privs & SYSOP_CMD)) {
- tputs(Noperm);
- return 0;
- }
- if (m->stype == 'S') {
- myargc = msg = atoi(argv[1]);
- i = atoi(argv[2]);
- if ((argc < 3) || !msg || !i)
- tputs(NoMsgs);
- else {
- for ( ; myargc <= i; myargc++) {
- m->mbox[myargc].status |= BM_DELETE;
- statusCtl (m->area, "ctl", &m->mbox[myargc], myargc, 0);
- }
- if (!issysarea (m->area))
- m->change |= CHG_DELETE;
- tprintf("Msgs %d to %d Killed.\n", msg, i);
- }
- return 0;
- }
- if (m->mfile == NULLFILE) {
- tputs(Nomail);
- return 0;
- }
- /*If this is the KM command, setup myargv[]
- *to contain up to NARG message numbers - WG7J
- */
- if(m->stype == 'M') {
- myargc = 1;
- /* scan all messsages to find read ones */
- maxmsg = min(m->nmsgs,NARG-1);
- for(i=1;i<=maxmsg;i++){
- cmsg = &m->mbox[i];
- if(cmsg->status & BM_READ) { /*found a read msg!*/
- tmpbuf = mallocw(18); /*allocate space for the new argument*/
- myargv[myargc++] = itoa(i,tmpbuf,10);
- }
- }
- if(myargc == 1) {
- tputs(NoMsgs);
- return 0;
- }
- argc = myargc;
- } else {
- if(argc == 1) {
- tprintf("Usage: K%c #\n", m->stype);
- return 0;
- }
- /*simply point to the old arguments*/
- for(i=1;i<argc;i++)
- myargv[i] = argv[i];
- }
-
- for(i = 1; i < argc; ++i) {
- msg = atoi(myargv[i]);
- if(msg < 1 || msg > m->nmsgs) {
- tprintf(Badmsg,msg);
- continue;
- }
- switch (m->stype) {
- case 'U': m->mbox[msg].status &= ~BM_DELETE;
- tprintf("Msg %d Un-Killed.\n", msg);
- break;
- case 'A': m->mbox[msg].status &= ~BM_ONHOLD;
- tprintf("Msg %d Available.\n", msg);
- break;
- case 'H': m->mbox[msg].status |= BM_ONHOLD;
- tprintf("Msg %d Held.\n", msg);
- break;
- case 'T': m->mbox[msg].status &= ~BM_PERMANENT;
- tprintf("Msg %d Temporary.\n", msg);
- break;
- case 'P': m->mbox[msg].status |= BM_PERMANENT;
- tprintf("Msg %d Permanent.\n", msg);
- break;
- default : m->mbox[msg].status |= BM_DELETE;
- tprintf("Msg %d Killed.\n", msg);
- if (!issysarea (m->area))
- m->change |= CHG_DELETE;
- break;
- }
- statusCtl (m->area, "ctl", &m->mbox[msg], msg, 0);
- }
- /* If this was 'KM'
- * free the memory allocated for myargv[] - WG7J
- */
- if(m->stype == 'M') {
- for(i=1;i<argc;i++)
- free(myargv[i]);
- }
- return 0;
- }
-
- struct clparms {
- int nostatus,
- nodelete;
- long *hostsize;
- char name[20] ; /* Name of remote station */
- char area[64]; /* name of current mail area */
- FILE *mfile; /* mail data file pointer */
- struct let *mbox;
- int nmsgs; /* number of messages in this mail box */
- int isbbs;
- };
-
-
- static void
- close_notes (a, b, c)
- int a;
- void *b, *c;
- {
- struct clparms *cl;
- struct let *cmsg;
- char *line;
- char tstring[LINELEN], buf[256];
- char buf2[256];
- long size, diff;
- FILE *nfile;
- int i, nextisBID, numwritten = 0;
- long msgid;
- char *cp;
- int foundstatus;
-
- cl = (struct clparms *) b;
- line = tstring;
- sprintf(buf,"%s/CONTROL/%s.ctl",Mailspool,cl->area);
- remove (buf);
-
- fclose (cl->mfile);
- sprintf(buf,"%s/%s.txt",Mailspool,cl->area);
- sprintf(buf2,"%s/%s.bak",Mailspool,cl->area);
- remove (buf2); /* delete it here, just in case! */
- rename (buf, buf2);
- if ((cl->mfile = fopen(buf2,READ_TEXT)) == NULLFILE) {
- rmlock(Mailspool,cl->area);
- free (cl);
- return;
- }
- if ((nfile = fopen(buf,WRITE_TEXT)) == NULLFILE) {
- fclose(cl->mfile);
- rmlock(Mailspool,cl->area);
- free (cl);
- return;
- }
- /* copy tmp file back to notes file */
- for (cmsg = &cl->mbox[1],i = 1; i <= cl->nmsgs; i++, cmsg++) {
- fseek(cl->mfile,cmsg->start,0);
- pwait (NULL);
- cmsg->start = ftell(nfile);
- size = cmsg->size;
- diff = 0;
- foundstatus = 0;
- /* It is not possible to delete messages if nodelete is set */
- if ((cmsg->status & BM_DELETE) && !cl->nodelete)
- continue;
- nextisBID = 0;
- /* copy the header */
- while (size > 0 && fgets(line,LINELEN,cl->mfile) != NULLCHAR) {
- pwait(NULL); /* can cause problems if exiting NOS */
- if (nextisBID && (cp=strstr(line,"AA")) != NULLCHAR) {
- /*what follows is the message-number*/
- msgid = atol(cp+2);
- nextisBID = 0;
- }
- if (!strncmp (line, Hdrs[RECEIVED], strlen(Hdrs[RECEIVED])))
- nextisBID = 1;
- if (!strncmp (line, Hdrs[STATUS], strlen(Hdrs[STATUS])))
- foundstatus = 1;
- size -= strlen(line);
- if (*line == '\n') {
- #ifdef notagain
- if (cmsg->status & BM_FORWARDED) {
- fprintf(nfile,"%s%s\n",Hdrs[XFORWARD],
- cl->name);
- diff += (strlen(Hdrs[XFORWARD]) + strlen(cl->name) + 1);
- }
- #endif
- if (!foundstatus && (cmsg->status & BM_READ) != 0 && !cl->nostatus) {
- fprintf(nfile,"%sR\n",Hdrs[STATUS]);
- diff += (strlen(Hdrs[STATUS]) + 2);
- }
- fprintf(nfile,"\n");
- break;
- }
- fputs(line,nfile);
- pwait(NULL); /* can cause problems if exiting NOS */
- }
- pwait (NULL);
- while (size > 0 && fgets(line,LINELEN,cl->mfile) != NULLCHAR) {
- pwait(NULL); /* can cause problems if exiting NOS */
- if (!cl->nostatus && !strncmp (line, Hdrs[RRECEIPT], strlen(Hdrs[RRECEIPT]))
- && !strcmp (cl->name, cl->area) && (cmsg->status & BM_RRECEIPT)) {
- fputs("Return-Receipt-Sent\n", nfile);
- diff -= strlen(line);
- diff += 20;
- }
- else
- fputs(line,nfile);
- size -= strlen(line);
- pwait(NULL); /* dont want no damaged files */
- if (ferror(nfile)) {
- (void) fclose(nfile);
- fclose(cl->mfile);
- rmlock(Mailspool,cl->area);
- free (cl);
- return;
- }
- }
- cmsg->status &= BM_READ;
- cmsg->size += diff;
- updateCtl (cl->area, cmsg);
- fflush(nfile);
- numwritten++;
- }
- if (!cl->isbbs && !stricmp(cl->name,cl->area))
- *cl->hostsize = ftell(nfile); /* Update the size of our hosts' mailbox */
- /* potientially dangerous! */
- /* remove a zero length file */
- if (!numwritten) {
- (void) fclose(nfile);
- (void) unlink(buf);
- } else
- (void) fclose(nfile);
- fclose (cl->mfile);
- remove (buf2); /* leave it around, for now! NOT! */
- rmlock(Mailspool,cl->area);
- free (cl->mbox);
- free (cl);
- pwait(NULL);
- return;
- }
-
-
-
- /* close the temp file while coping mail back to the mailbox */
- int
- closenotes(m)
- struct mbx *m;
- {
- int i, nostatus, nodelete = 0;
- struct clparms *cl;
-
- if (m->mfile == NULLFILE)
- return 0;
- nostatus = issysarea(m->area);
-
- /* Allow any user to delete from area names starting with 'nts' */
- if(!strnicmp(m->area,"nts",3))
- nostatus = 0;
- if(!m->change || nostatus) { /* no changes were made (or bulletin) */
- mfclose(m);
- m->mboxsize = 0;
- return 0;
- }
- /* If this area is not our own private message area, then we will not add a
- * Status line to indicate that the message has been read.
- */
- if (strcmp (m->area, m->name)) {
- nostatus = 1;
- /* Don't delete messages from public message areas unless you are
- * a SYSOP.
- */
- nodelete = !(m->privs & SYSOP_CMD);
- }
- /* Allow any user to delete from area names starting with 'nts' */
- if(!strnicmp(m->area,"nts",3))
- nodelete = 0;
- /* If not a SYSOP, not an "nts" area, not our area, AND deletions, must be BBS forward */
- if (nodelete && (m->change & CHG_DELETE)) {
- nodelete = 0;
- log(-1,"MBOX forwarding rewrite of personal area '%s' by %s ", m->area, m->name);
- }
-
- if(nostatus && nodelete) {
- mfclose(m);
- m->mboxsize = 0;
- return 0;
- }
- scanmail(m);
- if(lockit(m))
- return -1;
- cl = (struct clparms *) malloc (sizeof (struct clparms));
- cl->nodelete = nodelete;
- cl->nostatus = nostatus;
- cl->hostsize = &m->mysize;
- cl->isbbs = (m->sid & MBX_SID);
- strcpy (cl->name, m->name);
- strcpy (cl->area, m->area);
- cl->mfile = m->mfile;
- cl->nmsgs = m->nmsgs;
- cl->mbox = m->mbox;
- newproc("Closing notefile", 2560, close_notes, 0, cl, 0, 0);
- pwait(NULL);
- m->mfile = NULLFILE;
- m->mbox = (struct let *) 0;
- mfclose(m);
- m->mboxsize = 0;
- return 0;
- }
-
-
- /* Returns 1 if name is in the given area file, 0 otherwise */
- static int
- is_area(name, listfile)
- char *name, *listfile;
- {
- char buf[LINELEN], *cp;
- FILE *fp;
-
- if((fp = fopen(listfile,READ_TEXT)) == NULLFILE)
- return 0;
- while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
- /* The first word on each line is all that matters */
- if(isalnum(buf[0])) { /* skip comments */
- if((cp = strpbrk(buf," \t")) != NULLCHAR)
- *cp = '\0';
- /*This could be a line with just the area name,
- *ie terminated with 'CR/LF' - WG7J
- */
- if((cp = strchr(buf,'\n')) != NULLCHAR)
- *cp = '\0';
- if(stricmp(name,buf) == 0) { /* found it */
- fclose(fp);
- return 1;
- }
- }
- }
- fclose(fp);
- return 0;
- }
-
- /* Returns 1 if name is a public message Area, 0 otherwise */
- int
- isarea(name)
- char *name;
- {
- return (is_area (name, Arealist));
- }
-
- /* Returns 1 if name is a public message Area, 0 otherwise */
- int
- issysarea(name)
- char *name;
- {
- return (is_area (name, AreaSlist));
- }
-
- int
- lockit(m)
- struct mbx *m;
- {
- int c, cnt = 0;
-
- while(mlock(Mailspool,m->area)) {
- mspause(1000L/MSPTICK); /* Wait one second */
- if(++cnt == 10) {
- char buf[80];
- sprintf (buf, "Mail file '%s' is busy, Abort or *Retry ? ", m->area);
- cnt = 0;
- c = tkeywait(buf,1);
- if (c == 'A' || c == 'a' || c == EOF) {
- mfclose(m);
- return 1;
- }
- }
- }
- return 0;
- }
-
- /* read the next message or the current one if new */
- int
- doreadnext(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mbx *m;
- char buf[10], *newargv[2];
- m = (struct mbx *) p;
- if (m->mfile == NULLFILE)
- return 0;
- if ((m->mbox[m->current].status & BM_READ) != 0) {
- if (m->current == 1 && m->anyread == 0)
- ;
- else if (m->current < m->nmsgs) {
- m->current++;
- } else {
- tprintf("Last message\n");
- return 0;
- }
- }
- sprintf(buf,"%d",m->current);
- newargv[0] = "read";
- newargv[1] = buf;
- return doreadmsg(2,newargv,p);
- }
-
- extern int MbRead;
-
- /* display message on the crt given msg number */
- /* Modified to allow the 'RM' command, 920307 - WG7J */
- int
- doreadmsg(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mbx *m;
- register int c, col, lin;
- unsigned char buf[MAXBUF+2], *cp, *cp2;
- char *subj = 0, *theto = 0;
- int msg, cnt, i, usemore=0, verbose, mbxheader, pathcol;
- int header, lastheader;
- long size;
- char *myargv[NARG];
- int myargc;
- int maxmsg;
- struct let *cmsg;
- char *tmpbuf;
- char *returnreceipt;
- #ifdef nope /* was USERLOG */
- long msgid;
- #endif
-
- m = (struct mbx *) p;
-
- /*Check for read-permissions - WG7J */
- if(m->privs & NO_READCMD) {
- tputs(Noperm);
- return 0;
- }
- #ifdef MBFWD
- if (m->stype == 'O')
- return (dombroute (argc, argv, p));
- #endif
- if (m->mfile == NULLFILE) {
- tprintf(Nomail);
- return 0;
- }
- if((lin=m->morerows) != 0)
- usemore = 1; /* Display More prompt */
-
- /*If this is the RM or VM command, setup myargv[]
- *to contain up to NARG message numbers - WG7J
- */
- if(m->stype == 'M') {
- myargc = 1;
- /* scan all messsages to find unread ones */
- maxmsg = min(m->nmsgs,NARG-1);
- for(i=1;i<=maxmsg;i++){
- cmsg = &m->mbox[i];
- if(!(cmsg->status & BM_READ)) { /*found an unread msg!*/
- tmpbuf = mallocw(18); /*allocate space for the new argument*/
- myargv[myargc++] = itoa(i,tmpbuf,10);
- }
- }
- argc = myargc;
- } else {
- /*simply point to the old arguments*/
- for(i=1;i<argc;i++)
- myargv[i] = argv[i];
- }
- if(argc == 1) {
- tputs("Usage: Read/Verbose #\n");
- return 0;
- }
- m->state = MBX_READ;
- for(i = 1; i < argc; ++i) {
- msg = atoi(myargv[i]);
- if( msg < 1 || msg > m->nmsgs) {
- tprintf(Badmsg,msg);
- goto iamdone;
- }
- MbRead++;
- fseek(m->mfile,m->mbox[msg].start,0);
- #ifdef nope /* was USERLOG */
- /* Check the ID number of this message and
- * adjust new lastread count, if needed - WG7J
- */
- fgets(buf,MAXBUF+2,m->mfile); /* the 'From ' line */
- fgets(buf,MAXBUF+2,m->mfile); /* the 'Received: ' line */
- fgets(buf,MAXBUF+2,m->mfile); /* the ' ID' line */
- /* find id number */
- if((cp=strstr(buf,"AA")) != NULLCHAR) {
- /*what follows is the message-number*/
- msgid = atol(cp+2);
- if((msgid > m->lastread) && (msgid > m->newlastread))
- m->newlastread = msgid;
- }
- fseek(m->mfile,m->mbox[msg].start,0);
- #endif
- #ifdef USERLOG
- if((m->mbox[msg].bid > m->lastread) && (m->mbox[msg].bid > m->newlastread))
- m->newlastread = m->mbox[msg].bid;
- #endif
-
- m->anyread = 1;
- returnreceipt = 0;
- size = m->mbox[msg].size;
- m->current = msg;
- header = NOHEADER;
- mbxheader = 0;
- if((*argv[0] == 'v') || (m->stype == 'H'))
- verbose = 1; /* display all header lines */
- else
- verbose = 0;
-
- m->inmessage = 1;
- if(m->stype != 'M')
- bbscolorcls (m);
- bbscolorchange (m, "07");
- tprintf("Message #%d %s\n", msg,
- m->mbox[msg].status & BM_ONHOLD ? "[On Hold - Awaiting Review of SYSOP]" :
- m->mbox[msg].status & BM_DELETE ? "[Deleted]" : "");
-
- if ((m->mbox[msg].status & (BM_ONHOLD | BM_DELETE)) && !(m->privs & SYSOP_CMD))
- continue;
-
- /* When you have sysop privs,
- * only mark your own private area as read and changed.
- * other areas, only mark as read, NOT changed !
- * for regular users, simply mark all as read and changed.
- * That way sysops can read other's mail without
- * marking stuff read that really wasn't read by
- * the right person !
- * for regular users, simply mark as read.
- * 910312 - WG7J
- */
- if(!(m->mbox[msg].status & BM_READ)) {
- m->mbox[msg].status |= BM_READ;
- /* regular users */
- if(!issysarea (m->area) && (!(m->privs & SYSOP_CMD) || \
- ((m->privs & SYSOP_CMD) && !strcmp(m->name,m->area)))) /*sysops*/
- m->change |= CHG_READ;
- m->newmsgs--;
- }
- --lin;
- col = 0;
- while (!feof(m->mfile) && size > 0) {
- for (col = 0; col < MAXBUF;) {
- c = getc(m->mfile);
- size--;
- if (feof(m->mfile) || size == 0) /* end this line */
- break;
- if (c == '\t') {
- cnt = col + 8 - (col & 7);
- if (cnt >= MAXBUF) /* end this line */
- break;
- while (col < cnt)
- buf[col++] = ' ';
- } else {
- if (c == '\n')
- break;
- buf[col++] = c;
- }
- }
- if(col < MAXBUF)
- buf[col++] = '\n';
- buf[col] = '\0';
- if(mbxheader > 0) {
- /* Digest R: lines and display as a Path: line */
- if(strnicmp(buf,"R:",2) != 0 ||
- (cp = strchr(buf,'@')) == NULLCHAR) {
- tputc('\n');
- mbxheader = -1; /* don't get here again */
- verbose = 1;
- }
- else {
- if(*(++cp) == ':')
- ++cp;
- for(cp2 = cp; isalnum(*cp2); ++cp2) ;
- *cp2 = '\0';
- if(mbxheader++ == 1) {
- tputs(Hdrs[PATH]);
- pathcol = 5;
- --lin;
- }
- else {
- tputc('!');
- if(++pathcol + strlen(cp) > MAXCOL-3){
- tputs("\n ");
- pathcol = 5;
- --lin;
- }
- }
- tputs(cp);
- pathcol += strlen(cp);
- ++lin; /* to allow for not printing it later */
- }
- }
- if(col == 1 && !mbxheader) {
- bbscolorchange (m, "0B");
- /* last header line reached */
- if (!verbose)
- mbxheader = 1;
- }
- if(verbose)
- /* tputs(buf); */
- colorprintf (NULLCHAR, m->usecolor, buf);
- if (!strncmp (Hdrs[RRECEIPT], buf, strlen(Hdrs[RRECEIPT])))
- returnreceipt = strdup(&buf[strlen(Hdrs[RRECEIPT])]);
- if(!verbose && !mbxheader){
- lastheader = header;
- if(!isspace(*buf))
- header = htype(buf);
- else
- header = lastheader;
- switch(header) {
- case SUBJECT: subj = strdup (&buf[strlen(Hdrs[SUBJECT]) - 4]);
- tputs(buf);
- break;
- case TO: theto = strdup (&buf[strlen(Hdrs[TO])]);
- case CC:
- case FROM:
- case DATE:
- case REPLYTO:
- case APPARTO:
- case ERRORSTO:
- case XMAILGROUP:
- case ORGANIZATION:
- tputs(buf);
- break;
- default:
- ++lin;
- }
- }
- col = 0;
- if(usemore && --lin == 0){
- if(m->type == TELNET || m->type == TIP)
- c = tkeywait("--More--",0);
- else /* For AX.25 and NET/ROM connects - WG7J */
- c = mykeywait(anymore, m);
- lin = m->morerows;
- if(c == -1 || c == 'q' || c == 'Q')
- break;
- #ifdef TNOS_68K
- if(c == '\l' || c == '\r')
- #else
- if(c == '\n' || c == '\r')
- #endif
- lin = 1;
- }
- }
- if (returnreceipt && !(m->mbox[msg].status & BM_RRECEIPT)) {
- struct mbx *mm;
- m->mbox[msg].status |= BM_RRECEIPT;
- rip (returnreceipt); /* strip off <CR> */
- tprintf ("[Sending return receipt to '%s']\n", returnreceipt);
- mm = (struct mbx *) malloc (sizeof (struct mbx));
- mm->tomsgid = mm->date = mm->origbbs = mm->tofrom = NULLCHAR;
- mm->origto = returnreceipt;
- mm->subject = subj;
- rip (subj); /* strip off <CR> */
- subj[0] = subj[1] = 'R';
- subj[2] = ':';
- subj[3] = ' ';
- mm->stype = 'P';
- strcpy (mm->name, m->name);
- if ((mm->tfile = tmpfile()) != NULLFILE) {
- struct list *cclist = NULLLIST;
- char fullfrom[MBXLINE];
- addlist(&cclist, returnreceipt, 0, returnreceipt);
- sprintf (fullfrom, "%s@%s", m->name, Hostname);
- mbx_data (mm, NULLLIST, NULLCHAR);
- rip (theto); /* strip off the <CR> */
- fprintf (mm->tfile, "Message received - Originally addressed to: '%s'\n", theto);
- fseek(mm->tfile, 0L, 0); /* rewind file */
- queuejob (mm->tfile, Hostname, cclist, fullfrom);
- fclose (mm->tfile);
- del_list(cclist);
- smtptick(NULL); /* wake up SMTP to send mail */
- }
- free (mm);
- free(returnreceipt);
- }
- free (subj);
- free (theto);
- m->inmessage = 0;
- }
- iamdone:
- /* If this was 'RM' or 'VM',
- * free the memory allocated for myargv[] - WG7J
- */
- if(m->stype == 'M') {
- for(i=1;i<argc;i++)
- free(myargv[i]);
- }
- return 0;
- }
-
- /* Set up m->to when replying to a message. The subject is returned in
- * m->line.
- */
- int
- mbx_reply(argc,argv,m,cclist,rhdr)
- int argc;
- char *argv[];
- struct mbx *m;
- struct list **cclist; /* Pointer to buffer for pointers to cc recipients */
- char **rhdr; /* Pointer to buffer for extra reply headers */
- {
- char subject[MBXLINE], *msgid = NULLCHAR, *date = NULLCHAR;
- char *cp;
- int msg, lastheader, header = NOHEADER;
- long size;
-
- /* Free anything that might be allocated
- * since the last call to mbx_to() or mbx_reply()
- */
- free(m->to);
- m->to = NULLCHAR;
- free(m->tofrom);
- m->tofrom = NULLCHAR;
- free(m->tomsgid);
- m->tomsgid = NULLCHAR;
- free(m->origto);
- m->origto = NULLCHAR;
- subject[0] = '\0';
-
- if(argc == 1)
- msg = m->current;
- else
- msg = atoi(argv[1]);
- if (m->mfile == NULLFILE) {
- if(m->sid & MBX_SID)
- tputs("NO - ");
- tputs(Nomail);
- return 0;
- }
- if(msg < 1 || msg > m->nmsgs) {
- if(m->sid & MBX_SID)
- tputs("NO - ");
- tputs(Badmsg);
- return -1;
- }
- fseek(m->mfile,m->mbox[msg].start,0);
- size = m->mbox[msg].size;
- m->current = msg;
- while(size > 0 && fgets(m->line,MBXLINE-1,m->mfile) != NULLCHAR) {
- size -= strlen(m->line);
- if(m->line[0] == '\n') /* end of header */
- break;
- rip(m->line);
- lastheader = header;
- if(!isspace(m->line[0])) {
- header = htype(m->line);
- lastheader = NOHEADER;
- }
- switch(header) {
- case SUBJECT:
- if(strlen(m->line) > 11 && !strnicmp(&m->line[9],"Re:",3))
- strcpy(subject,&m->line[9]);
- else
- sprintf(subject,"Re: %s",&m->line[9]);
- break;
- case FROM:
- if(m->to == NULLCHAR && (cp = getaddress(m->line,0)) !=
- NULLCHAR)
- m->to = strdup(cp);
- break;
- case REPLYTO:
- if((cp = getaddress(m->line,0)) != NULLCHAR) {
- free(m->to);
- m->to = strdup(cp);
- }
- break;
- case MSGID:
- free(msgid);
- msgid = strdup(&m->line[12]);
- break;
- case DATE:
- free(date);
- date = strdup(&m->line[6]);
- break;
- #ifdef notdef
- /* don't want a reply back to myself - WG7J */
- case TO:
- case APPARTO:
- #endif
- case CC:
- /* Get addresses on To, Cc and Apparently-To lines */
- cp = m->line;
- m->line[strlen(cp)+1] = '\0'; /* add extra null at end */
- for(;;) {
- if((cp = getaddress(cp,lastheader == header ||
- cp != m->line)) == NULLCHAR)
- break;
- addlist(&cclist,cp,0,cp);
- /* skip to next address, if any */
- cp += strlen(cp) + 1;
- }
- break;
- }
- }
- if(msgid != NULLCHAR || date != NULLCHAR) {
- *rhdr = mallocw(LINELEN);
- sprintf(*rhdr,"In-Reply-To: your message ");
- if(date != NULLCHAR) {
- sprintf(m->line,"of %s.\n",date);
- strcat(*rhdr,m->line);
- if(msgid != NULLCHAR)
- strcat(*rhdr," ");
- }
- if(msgid != NULLCHAR) {
- sprintf(m->line,"%s\n",msgid);
- strcat(*rhdr,m->line);
- }
- free(msgid);
- free(date);
- }
- strcpy(m->line,subject);
- return 0;
- }
-
- #ifdef USERLOG
-
- /*get the last message listed/read
- *from the areaname.USR file
- *keeps track for each user.
- *February '92, WG7J
- */
- void
- getlastread(m)
- struct mbx *m;
- {
- FILE *Alog;
- char buf[256];
- char *cp;
- int found=0;
-
- m->lastread = m->newlastread = 0L;
-
- sprintf(buf,"%s/USERS/%s.usr",Mailspool,m->area);
- if ((Alog = fopen(buf,"r+")) == NULLFILE) {
- /* USR file doesn't exist, create it */
- if((Alog = fopen(buf,"w")) == NULLFILE)
- return;
- /* Add this user as first one */
- sprintf(buf,"%s 0\n",m->name);
- fputs(buf,Alog);
- fclose(Alog);
- return;
- }
- /*Find user in the usr file for this area*/
- for(;;) {
- if(fgets(buf,sizeof(buf),Alog) == NULLCHAR)
- break;
- if((cp=strchr(buf,' ')) != NULLCHAR)
- *cp = '\0';
- if(!stricmp(m->name,buf)) {
- /*found user*/
- cp++;
- while(*cp == ' ') /*skip blanks*/
- cp++;
- m->lastread = atol(cp);
- found = 1;
- break;
- }
- }
- if(!found) {
- /*Add user*/
- sprintf(buf,"%s 0\n",m->name);
- fputs(buf,Alog);
- }
- fclose(Alog);
- return;
- }
-
- /* Write the new last read id number to the USR file - WG7J
- * only update if this is not a bbs,
- * current area is a public area and not 'help',
- * or anything that starts with 'sys',
- * and a new message was actually listed/read
- */
- void
- setlastread(m)
- struct mbx *m;
- {
- FILE *Alog, *tfile;
- char buf[256];
- char tmpname[80];
- char *cp;
- int doit = 0;
-
- if((m->sid & MBX_SID) || (m->newlastread <= m->lastread) )
- return;
-
- /* if(issysarea(m->area))
- if ((m->privs & MBX_SYSOP) || (stricmp(m->area, "help")))
- doit = 1; */
- if(isarea(m->area) && strcmp(m->area, "help"))
- doit = 1;
- if ((m->privs & SYSOP_CMD) && issysarea(m->area))
- doit = 1;
-
- if (doit) {
-
- #ifdef notdef
- tprintf("SETLAST: %d\n",m->newlastread);
- #endif
-
-
- sprintf(buf,"%s/USERS/%s.usr",Mailspool,m->area);
-
- /* Rename the USR file to a tempfile */
- tmpnam(tmpname);
- if(rename(buf,tmpname))
- /* Can't rename ??? */
- return;
-
- if((Alog = fopen(buf,"w")) == NULLFILE) {
- /* can't creat new USR file ???*/
- rename(tmpname,buf); /* try to undo the damage */
- return;
- }
-
- if((tfile = fopen(tmpname,"r")) == NULLFILE)
- /* can't open renamed file ??? */
- return;
-
- /*Write all users back, but update this one!*/
- while(fgets(buf,sizeof(buf),tfile) != NULLCHAR) {
- if((cp=strchr(buf,' ')) != NULLCHAR)
- *cp = '\0';
- if(!stricmp(m->name,buf)) {
- /*found this user*/
- sprintf(buf,"%s %lu\n",m->name,m->newlastread);
- } else
- *cp = ' '; /* restore the space !*/
- fputs(buf,Alog);
- }
- fclose(tfile);
- unlink(tmpname);
- fclose(Alog);
- }
- return;
- }
-
- #endif /*USERLOG*/
-
- void
- scanmail(m) /* Get any new mail */
- struct mbx *m;
- {
- long diff;
-
- if ((diff = isnewmail(m)) == 0L)
- return;
- if(lockit(m))
- return;
- initnotes(m);
- rmlock(Mailspool,m->area);
- }
-
- /* Check the current mailbox to see if new mail has arrived.
- * Returns the difference in size.
- */
- static long
- isnewmail(m)
- struct mbx *m;
- {
- char buf[256];
-
- sprintf(buf,"%s/%s.txt",Mailspool,m->area);
- return fsize(buf) - m->mboxsize;
- }
-
- /* Check if the private mail area has changed */
- long
- isnewprivmail(m)
- struct mbx *m;
- {
- long cnt;
- char buf[256];
-
- sprintf(buf,"%s/%s.txt",Mailspool,m->name);
- cnt = m->mysize;
- m->mysize = fsize(buf);
- return m->mysize - cnt; /* != 0 not more than once */
- }
-
-
- void
- notifynewmail (m)
- struct mbx *m;
- { /* not a BBS, but from within ANY area */
- if (!(m->sid & MBX_SID) && (isnewprivmail(m) > 0L)) {
- tprintf("\007You have new mail in your personal area (%s). Please Kill when read!\n", m->name);
- usflush(Curproc->output);
- }
- }
-
- #endif
-
- /* This function returns the length of a file. The proper thing would be
- * to use stat(), but it fails when using DesqView together with Turbo-C
- * code.
- */
- long
- fsize(name)
- char *name;
- {
- long cnt;
- FILE *fp;
-
- if((fp = fopen(name,READ_TEXT)) == NULLFILE)
- return -1L;
- fseek(fp,0L,2);
- cnt = ftell(fp);
- /* cnt = filelength (fileno(fp)); */
- fclose(fp);
- return cnt;
- }
-
- /* close the temporary mail file */
- static void
- mfclose(m)
- struct mbx *m;
- {
- if(m->mfile != NULLFILE)
- fclose(m->mfile);
- m->mfile = NULLFILE;
- #ifdef SETVBUF
- free(m->stdoutbuf);
- m->stdoutbuf = NULLCHAR;
- #endif
- }
-
-
- /* erase a previous prompt via backspaces */
- void
- backEmUp (len)
- int len;
- {
- int i;
- /* Get rid of the prompt */
- for(i=len;i != 0;i--)
- tputc('\b');
- for(i=len;i != 0;i--)
- tputc(' ');
- for(i=len;i != 0;i--)
- tputc('\b');
- tflush ();
- }
-
-
- /* Print prompt and read one character, telnet version */
- int
- tkeywait(prompt,flush)
- char *prompt; /* Optional prompt */
- int flush; /* Flush queued input? */
- {
- int c, oldimode,oldomode;
-
- if(flush && socklen(Curproc->input,0) != 0)
- recv_mbuf(Curproc->input,NULL,0,NULLCHAR,0); /* flush */
- if(prompt == NULLCHAR)
- prompt = "Hit enter to continue";
- tprintf("%s%c%c%c",prompt,IAC,WILL,TN_ECHO);
- usflush(Curproc->output);
-
- /* discard the response */
-
- oldimode = sockmode(Curproc->input,SOCK_BINARY);
- oldomode = sockmode(Curproc->output,SOCK_BINARY);
-
- while((c = rrecvchar(Curproc->input)) == IAC){
- c = rrecvchar(Curproc->input);
- if(c > 250 && c < 255)
- rrecvchar(Curproc->input);
- }
-
- sockmode(Curproc->output,oldomode);
- sockmode(Curproc->input,oldimode);
-
- backEmUp (strlen(prompt));
- tprintf("%c%c%c",IAC,WONT,TN_ECHO);
- usflush(Curproc->output);
- return c;
- }
-
- /* Print -more- prompt and read reply,
- * AX.25 and NETROM version - WG7J
- * <CR> is taken as a 'Yes'
- */
- int
- mykeywait(prompt,m)
- char *prompt;
- struct mbx *m;
- {
- tputs(prompt);
- usflush(Curproc->output);
- if(recvline(m->user, m->line, MBXLINE) == -1) {
- return -1;
- }
- /* Only 'N' or 'n' really matters */
- if((*m->line == 'N') || (*m->line == 'n'))
- return -1;
- return 0;
- }